package mianshi;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.activation.MailcapCommandMap;

/**
 * 现在程序中有一组学生成绩数据（getScoreList()返回结果），每条数据为某个学生的某科成绩。学生成绩可能不是4科都有，可能有缺科。
 * 要求对这组数据进行数据转换和计算处理，转换成学生记录列表，每条记录里面有4科成绩和总成绩，并在此基础上计算全班的平均成绩。
 * 要求列表按总成绩从高到低排序。计算平均成绩时，请考虑缺课时的情况。
 * 需要注意的是，最终完成代码的代码质量（逻辑是否清晰，变量/方法命名是否合理等），将作为考察标准的一部分
 * 结果按以下格式控制台输出即可
 * 姓名    数学  语文  英语  物理  总成绩
 * 王五    77   82   90   65   434
 * 张三    65   84   89       316
 * 李四    89   76       76   313
 * …
 * 平均成绩 83.5  70.5  78   82.5  314.5
 */
public class ShowMeBug {
	public static void main(String[] args) {
		new ShowMeBug().test();
	}

	public void test() {
		List<ScoreVo> scoreList = getScoreList();
		// TODO 请编写代码实现题目要求
		// System.out.println(scoreList);
		// 所有学生的成绩
		Map<String, StudentVo> map = new HashMap<String, StudentVo>();
		// 存放单科成绩的map，key：课程名 value：List<Double>
		Map<String, List<Double>> scoreMap = new HashMap<String, List<Double>>();
		for (ScoreVo scoreVo : scoreList) {
			boolean isContain = map.containsKey(scoreVo.studentName);
			if (isContain) {
				//在map里面已经包含这个学生信息，只需要跟新相应学生的课程成绩即可
				StudentVo studentVo = map.get(scoreVo.studentName);
				updateStudentVoScore(scoreVo, studentVo, scoreMap);
			} else {
				// 这是第一次访问到这个学生，还没有在Map集合里面
				StudentVo studentVo = new StudentVo();
				updateStudentVoScore(scoreVo, studentVo, scoreMap);
				map.put(scoreVo.studentName, studentVo);
			}
		}
		
		Set<Entry<String, StudentVo>> studentVoEntrySet = map.entrySet();
		System.out.println("姓名\t数学\t语文\t英语\t物理\t总成绩");
		for (Entry<String, StudentVo> entry : studentVoEntrySet) {
			StudentVo studentVo = entry.getValue();
			System.out.println(entry.getKey() + "\t" + studentVo.getMathScore()
			 								  + "\t" + studentVo.getChineseScore()
			 								  + "\t" + studentVo.getEnglishScore()
			 								  + "\t" + studentVo.getPhysicalScore()
			 								  + "\t" + studentVo.getTotalScore());
		}
		
		Set<Entry<String, List<Double>>> scoreEntrySet = scoreMap.entrySet();
		Map<String, Double> avgScoreMap = new HashMap<String, Double>();
		for (Entry<String, List<Double>> entry : scoreEntrySet) {
			switch (entry.getKey()) {
			case "物理":
				avgScoreMap.put("物理", getAvgScore(entry.getValue()));
				break;
			case "数学":
				avgScoreMap.put("数学", getAvgScore(entry.getValue()));
				break;
			case "语文":
				avgScoreMap.put("语文", getAvgScore(entry.getValue()));
				break;
			case "英语":
				avgScoreMap.put("英语", getAvgScore(entry.getValue()));
				break;
			default:
				break;
			}
		}
		
		System.out.println("平均成绩" + "\t" + avgScoreMap.get("数学")
								      + "\t" + avgScoreMap.get("语文")
								      + "\t\t" + avgScoreMap.get("英语")
								      + "\t" + avgScoreMap.get("物理"));
		// System.out.println(scoreList.size());
	}

	// 计算这门课的平均值
	private double getAvgScore(List<Double> list) {
		double total = 0.0;
		for (Double score : list) {
			total += score;
		}
		return total / list.size();
	}

	private void updateStudentVoScore(ScoreVo scoreVo, StudentVo studentVo, Map<String, List<Double>> map) {
		switch (scoreVo.courseName) {
		case "数学":
			studentVo.setMathScore(scoreVo.score);
			
			List<Double> mathList = map.get("数学");
			if (mathList == null) {// 这个课程是第一次放进来
				mathList = new ArrayList<Double>();
				mathList.add(scoreVo.score);
				map.put("数学", mathList);
			} else {
				mathList.add(scoreVo.score);
			}
			break;
		case "语文":
			studentVo.setChineseScore(scoreVo.score);
			
			List<Double> chineseList = map.get("语文");
			if (chineseList == null) {// 这个课程是第一次放进来
				chineseList = new ArrayList<Double>();
				chineseList.add(scoreVo.score);
				map.put("语文", chineseList);
			} else {
				chineseList.add(scoreVo.score);
			}
			break;
		case "物理":
			studentVo.setPhysicalScore(scoreVo.score);
			
			List<Double> physicalList = map.get("物理");
			if (physicalList == null) {// 这个课程是第一次放进来
				physicalList = new ArrayList<Double>();
				physicalList.add(scoreVo.score);
				map.put("物理", physicalList);
			} else {
				physicalList.add(scoreVo.score);
			}
			break;
		case "英语":
			studentVo.setEnglishScore(scoreVo.score);
			
			List<Double> englishList = map.get("英语");
			if (englishList == null) {// 这个课程是第一次放进来
				englishList = new ArrayList<Double>();
				englishList.add(scoreVo.score);
				map.put("英语", englishList);
			} else {
				englishList.add(scoreVo.score);
			}
			break;
		default:
			break;
		}
		// 没添加一门课程更新这个学生的总成绩
		double totalScore = studentVo.getTotalScore();
		studentVo.setTotalScore(totalScore + scoreVo.score);
	}

	public List<ScoreVo> getScoreList() {
		List<ScoreVo> scoreList = new ArrayList<ScoreVo>();
		scoreList.add(new ScoreVo("张三", "语文", 80));
		scoreList.add(new ScoreVo("张三", "物理", 76));
		scoreList.add(new ScoreVo("李四", "语文", 78));
		scoreList.add(new ScoreVo("茅十八", "英语", 65));
		//scoreList.add(new ScoreVo("李四", "数学", 88));
		scoreList.add(new ScoreVo("李四", "物理", 87));
		scoreList.add(new ScoreVo("王五", "语文", 67));
		scoreList.add(new ScoreVo("张三", "数学", 76));
		scoreList.add(new ScoreVo("李四", "英语", 89));
		scoreList.add(new ScoreVo("王五", "数学", 65));
		scoreList.add(new ScoreVo("赵六", "物理", 95));
		scoreList.add(new ScoreVo("王五", "英语", 78));
		scoreList.add(new ScoreVo("王五", "物理", 65));
		scoreList.add(new ScoreVo("赵六", "语文", 89));
		scoreList.add(new ScoreVo("赵六", "英语", 87));
		scoreList.add(new ScoreVo("黄七", "语文", 78));
		scoreList.add(new ScoreVo("黄七", "数学", 65));
		scoreList.add(new ScoreVo("刘八", "英语", 87));
		scoreList.add(new ScoreVo("张三", "英语", 56));
		scoreList.add(new ScoreVo("黄七", "物理", 76));
		scoreList.add(new ScoreVo("刘八", "数学", 89));
		scoreList.add(new ScoreVo("黄七", "英语", 98));
		scoreList.add(new ScoreVo("刘八", "语文", 56));
		scoreList.add(new ScoreVo("刘八", "物理", 76));
		scoreList.add(new ScoreVo("钱九", "语文", 88));
		scoreList.add(new ScoreVo("钱九", "数学", 67));
		scoreList.add(new ScoreVo("茅十八", "数学", 43));
		scoreList.add(new ScoreVo("钱九", "英语", 75));
		scoreList.add(new ScoreVo("茅十八", "语文", 45));
		scoreList.add(new ScoreVo("茅十八", "物理", 56));

		return scoreList;
	}

	class ScoreVo {
		public String studentName;
		public String courseName;
		public double score;

		public ScoreVo(String studentName, String courseName, double score) {
			this.studentName = studentName;
			this.courseName = courseName;
			this.score = score;
		}

		public String toString() {
			return this.studentName + "\t" + this.courseName + "\t" + this.score;
		}
	}

	class StudentVo {
		private String name;
		private double chineseScore;
		private double mathScore;
		private double englishScore;
		private double physicalScore;
		private double totalScore;

		public StudentVo() {

		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public double getChineseScore() {
			return chineseScore;
		}

		public void setChineseScore(double chineseScore) {
			this.chineseScore = chineseScore;
		}

		public double getMathScore() {
			return mathScore;
		}

		public void setMathScore(double mathScore) {
			this.mathScore = mathScore;
		}

		public double getEnglishScore() {
			return englishScore;
		}

		public void setEnglishScore(double englishScore) {
			this.englishScore = englishScore;
		}

		public double getPhysicalScore() {
			return physicalScore;
		}

		public void setPhysicalScore(double physicalScore) {
			this.physicalScore = physicalScore;
		}

		public double getTotalScore() {
			return totalScore;
		}

		public void setTotalScore(double totalScore) {
			this.totalScore = totalScore;
		}
	}
}
